/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.entity.condition;

import com.inspur.edp.cef.entity.condition.advanceconditions.BqlConditionValue;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

/**
 * <p>FilterConditionBuilder过滤条件建造器，用于快速构造多个FilterCondition</p>
 * <p>FilterCondition类不再建议开发者直接创建使用，请使用FilterConditionBuilder</p>
 * <p>关于FilterConditionBuilder的示例可以访问<a href="https://open.inspures.com/openplat/#/doc/md/iGIX%2FiGIX_2305%2Fdevelop%2Flowcode-dev%2Fdev-sub%2Fbusiness-entity%2Ffeature-introduction%2FFilterConditionBuilder.md">这里</a>查看
 *
 * @author Kaixuan Shi
 * @since 2023/6/27
 */
public class FilterConditionBuilder {

    private List<FilterCondition> filterConditions;

    private FilterConditionBuilder() {
        this.filterConditions = new ArrayList<>();
    }

    private FilterConditionBuilder(List<FilterCondition> filterConditions) {
        this.checkBracketCount(filterConditions);
        this.filterConditions = filterConditions;
    }

    /**
     * 初始化过滤条件建造器
     */
    public static FilterConditionBuilder builder() {
        return new FilterConditionBuilder();
    }

    /**
     * 初始化过滤条件建造器，并将已有过滤条件添加到建造器中
     * <p>例：filterConditions 为 "age > 13 and age < 20"时，FilterConditionBuilder.builder(filterConditions).orEqual("age", 15).build()表示"age > 13 and age < 20 or age = 15"
     */
    public static FilterConditionBuilder builder(List<FilterCondition> filterConditions) {
        return new FilterConditionBuilder(filterConditions);
    }

    /**
     * 返回构造好的过滤条件，同时清空当前建造器以便继续建造其它过滤条件
     */
    public List<FilterCondition> build() {
        List<FilterCondition> currentResult = this.filterConditions;
        this.filterConditions = new ArrayList<>();
        return currentResult;
    }

    //region equal

    /**
     * 添加一个and过滤条件，比较符使用=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andEqual(String fieldName, String value) {
        return this.andEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Equal, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orEqual(String fieldName, String value) {
        return this.orEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Equal, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region notEqual

    /**
     * 添加一个and过滤条件，比较符使用!=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotEqual(String fieldName, String value) {
        return this.andNotEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用!=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotEqual, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用!=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotEqual(String fieldName, String value) {
        return this.orNotEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用!=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotEqual, value, expressValueType, ExpressRelationType.Or);
        return this;
    }
    //endregion

    //region greater

    /**
     * 添加一个and过滤条件，比较符使用>
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andGreater(String fieldName, String value) {
        return this.andGreater(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用>
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andGreater(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Greater, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用>
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orGreater(String fieldName, String value) {
        return this.orGreater(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用>
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orGreater(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Greater, value, expressValueType, ExpressRelationType.Or);
        return this;
    }
    //endregion

    //region greaterOrEqual

    /**
     * 添加一个and过滤条件，比较符使用>=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andGreaterOrEqual(String fieldName, String value) {
        return this.andGreaterOrEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用>=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andGreaterOrEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.GreaterOrEqual, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用>=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orGreaterOrEqual(String fieldName, String value) {
        return this.orGreaterOrEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用>=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orGreaterOrEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.GreaterOrEqual, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region less

    /**
     * 添加一个and过滤条件，比较符使用<
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLess(String fieldName, String value) {
        return this.andLess(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用<
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLess(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Less, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用<
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLess(String fieldName, String value) {
        return this.orLess(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用<
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLess(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Less, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region lessOrEqual

    /**
     * 添加一个and过滤条件，比较符使用<=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLessOrEqual(String fieldName, String value) {
        return this.andLessOrEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用<=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLessOrEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LessOrEqual, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用<=
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLessOrEqual(String fieldName, String value) {
        return this.orLessOrEqual(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用<=
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLessOrEqual(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LessOrEqual, value, expressValueType, ExpressRelationType.Or);
        return this;
    }
    //endregion

    //region between

    /**
     * 添加一个and过滤条件，比较符使用between(leastValue <= field <= maximumValue)
     * <p>内部构造了两个ExpressCompareType.GreaterOrEqual和ExpressCompareType.LessOrEqual比较关系的FilterCondition
     *
     * @param fieldName    属性名称
     * @param leastValue   最小值，值类型为ExpressValueType.Value
     * @param maximumValue 最大值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andBetween(String fieldName, String leastValue, String maximumValue) {
        return this.andBetween(fieldName, leastValue, maximumValue, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用between(leastValue <= field <= maximumValue)
     * <p>内部构造了两个ExpressCompareType.GreaterOrEqual和ExpressCompareType.LessOrEqual比较关系的FilterCondition
     *
     * @param fieldName        属性名称
     * @param leastValue       最小值
     * @param maximumValue     最大值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andBetween(String fieldName, String leastValue, String maximumValue, ExpressValueType expressValueType) {
        List<FilterCondition> filterConditions = new ArrayList<>(2);
        filterConditions.add(
                new FilterCondition(0, fieldName, ExpressCompareType.GreaterOrEqual, leastValue, 0,
                        ExpressRelationType.And, expressValueType));
        filterConditions.add(
                new FilterCondition(0, fieldName, ExpressCompareType.LessOrEqual, maximumValue, 0,
                        ExpressRelationType.Empty, expressValueType));
        this.addSubFilterConditions(filterConditions, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用between(leastValue <= field <= maximumValue)
     * <p>内部构造了两个ExpressCompareType.GreaterOrEqual和ExpressCompareType.LessOrEqual比较关系的FilterCondition
     *
     * @param fieldName    属性名称
     * @param leastValue   最小值，值类型为ExpressValueType.Value
     * @param maximumValue 最大值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orBetween(String fieldName, String leastValue, String maximumValue) {
        return this.orBetween(fieldName, leastValue, maximumValue, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用between(leastValue <= field <= maximumValue)
     * <p>内部构造了两个ExpressCompareType.GreaterOrEqual和ExpressCompareType.LessOrEqual比较关系的FilterCondition
     *
     * @param fieldName        属性名称
     * @param leastValue       最小值
     * @param maximumValue     最大值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orBetween(String fieldName, String leastValue, String maximumValue, ExpressValueType expressValueType) {
        List<FilterCondition> filterConditions = new ArrayList<>(2);
        filterConditions.add(
                new FilterCondition(0, fieldName, ExpressCompareType.GreaterOrEqual, leastValue, 0,
                        ExpressRelationType.And, expressValueType));
        filterConditions.add(
                new FilterCondition(0, fieldName, ExpressCompareType.LessOrEqual, maximumValue, 0,
                        ExpressRelationType.Empty, expressValueType));
        this.addSubFilterConditions(filterConditions, ExpressRelationType.Or);
        return this;
    }
    //endregion

    //region like

    /**
     * 添加一个and过滤条件，比较符使用like
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLike(String fieldName, String value) {
        return this.andLike(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用like
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLike(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Like, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用like
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLike(String fieldName, String value) {
        return this.orLike(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用like
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLike(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.Like, value, expressValueType, ExpressRelationType.Or);
        return this;
    }
    //endregion

    //region likeStartWith

    /**
     * 添加一个and过滤条件，比较符使用likeStartWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLikeStartWith(String fieldName, String value) {
        return this.andLikeStartWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用likeStartWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLikeStartWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LikeStartWith, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用likeStartWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLikeStartWith(String fieldName, String value) {
        return this.orLikeStartWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用likeStartWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLikeStartWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LikeStartWith, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region likeEndWith

    /**
     * 添加一个and过滤条件，比较符使用likeEndWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLikeEndWith(String fieldName, String value) {
        return this.andLikeEndWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用likeEndWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLikeEndWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LikeEndWith, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用likeEndWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLikeEndWith(String fieldName, String value) {
        return this.orLikeEndWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用likeEndWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLikeEndWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LikeEndWith, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region notLike

    /**
     * 添加一个and过滤条件，比较符使用notLike
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotLike(String fieldName, String value) {
        return this.andNotLike(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用notLike
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotLike(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotLike, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用notLike
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotLike(String fieldName, String value) {
        return this.orNotLike(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用notLike
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotLike(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotLike, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region notLikeStartWith

    /**
     * 添加一个and过滤条件，比较符使用notLikeStartWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotLikeStartWith(String fieldName, String value) {
        return this.andNotLikeStartWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用notLikeStartWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotLikeStartWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotLikeStartWith, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用notLikeStartWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotLikeStartWith(String fieldName, String value) {
        return this.orNotLikeStartWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用notLikeStartWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotLikeStartWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotLikeStartWith, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region notLikeEndWith

    /**
     * 添加一个and过滤条件，比较符使用notLikeEndWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotLikeEndWith(String fieldName, String value) {
        return this.andNotLikeEndWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用notLikeEndWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotLikeEndWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotLikeEndWith, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用notLikeEndWith
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotLikeEndWith(String fieldName, String value) {
        return this.orNotLikeEndWith(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用notLikeEndWith
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotLikeEndWith(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.NotLikeEndWith, value, expressValueType, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region is

    /**
     * 添加一个and过滤条件，比较符使用is（过滤属性值为null的数据）
     *
     * @param fieldName 属性名称
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andIsNull(String fieldName) {
        this.add(fieldName, ExpressCompareType.Is, null, ExpressValueType.Value, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用is（过滤属性值为null的数据）
     *
     * @param fieldName 属性名称
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orIsNull(String fieldName) {
        this.add(fieldName, ExpressCompareType.Is, null, ExpressValueType.Value, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region isNot

    /**
     * 添加一个and过滤条件，比较符使用isNot（过滤属性值不为null的数据）
     *
     * @param fieldName 属性名称
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andIsNotNull(String fieldName) {
        this.add(fieldName, ExpressCompareType.IsNot, null, ExpressValueType.Value, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用isNot（过滤属性值不为null的数据）
     *
     * @param fieldName 属性名称
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orIsNotNull(String fieldName) {
        this.add(fieldName, ExpressCompareType.IsNot, null, ExpressValueType.Value, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region in

    /**
     * 添加一个and过滤条件，比较符使用in
     *
     * @param fieldName 属性名称
     * @param values    要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andIn(String fieldName, List<?> values) {
        this.addInCondition(fieldName, ExpressCompareType.In, values, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个and过滤条件，比较符使用in
     *
     * @param fieldName         属性名称
     * @param bqlConditionValue bql，bql应返回要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andIn(String fieldName, BqlConditionValue bqlConditionValue) {
        this.addInCondition(fieldName, ExpressCompareType.In, bqlConditionValue, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用in
     *
     * @param fieldName 属性名称
     * @param values    要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orIn(String fieldName, List<?> values) {
        this.addInCondition(fieldName, ExpressCompareType.In, values, ExpressRelationType.Or);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用in
     *
     * @param fieldName         属性名称
     * @param bqlConditionValue bql，bql应返回要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orIn(String fieldName, BqlConditionValue bqlConditionValue) {
        this.addInCondition(fieldName, ExpressCompareType.In, bqlConditionValue, ExpressRelationType.Or);
        return this;
    }

    //endregion

    //region notIn

    /**
     * 添加一个and过滤条件，比较符使用not in
     *
     * @param fieldName 属性名称
     * @param values    要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotIn(String fieldName, List<?> values) {
        this.addInCondition(fieldName, ExpressCompareType.NotIn, values, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个and过滤条件，比较符使用not in
     *
     * @param fieldName         属性名称
     * @param bqlConditionValue bql，bql应返回要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andNotIn(String fieldName, BqlConditionValue bqlConditionValue) {
        this.addInCondition(fieldName, ExpressCompareType.NotIn, bqlConditionValue, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用not in
     *
     * @param fieldName 属性名称
     * @param values    要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotIn(String fieldName, List<?> values) {
        this.addInCondition(fieldName, ExpressCompareType.NotIn, values, ExpressRelationType.Or);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用not in
     *
     * @param fieldName         属性名称
     * @param bqlConditionValue bql，bql应返回要用in比较的值
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orNotIn(String fieldName, BqlConditionValue bqlConditionValue) {
        this.addInCondition(fieldName, ExpressCompareType.NotIn, bqlConditionValue, ExpressRelationType.Or);
        return this;
    }
    //endregion notIn

    //region likeIgnoreCase

    /**
     * 添加一个and过滤条件，比较符使用likeIgnoreCase
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLikeIgnoreCase(String fieldName, String value) {
        return this.andLikeIgnoreCase(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个and过滤条件，比较符使用likeIgnoreCase
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder andLikeIgnoreCase(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LikeIgnoreCase, value, expressValueType, ExpressRelationType.And);
        return this;
    }

    /**
     * 添加一个or过滤条件，比较符使用likeIgnoreCase
     *
     * @param fieldName 属性名称
     * @param value     值，值类型为ExpressValueType.Value
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLikeIgnoreCase(String fieldName, String value) {
        return this.orLikeIgnoreCase(fieldName, value, ExpressValueType.Value);
    }

    /**
     * 添加一个or过滤条件，比较符使用likeIgnoreCase
     *
     * @param fieldName        属性名称
     * @param value            值
     * @param expressValueType 值类型，仅支持ExpressValueType.Value和ExpressValueType.Expression
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder orLikeIgnoreCase(String fieldName, String value, ExpressValueType expressValueType) {
        this.add(fieldName, ExpressCompareType.LikeIgnoreCase, value, expressValueType, ExpressRelationType.Or);
        return this;
    }
    //endregion

    //region 在现有过滤条件后追加子条件

    /**
     * 在现有过滤条件后追加“AND”子条件
     * <p>例：subFilterConditions表示"age > 60 or age < 18"
     * <p>&emsp;&emsp;调用FilterConditionBuilder.builder().andEqual("location","3楼").and(subFilterConditions).build()
     * <p>&emsp;&emsp;表示" location = '3楼' and (age > 60 or age < 18) "
     *
     * @param subFilterConditions 0个或多个过滤条件，组成一个“AND”子条件
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder and(List<FilterCondition> subFilterConditions) {
        this.addSubFilterConditions(subFilterConditions, ExpressRelationType.And);
        return this;
    }

    /**
     * 在现有过滤条件后追加一个“AND”子条件
     * <p>例：FilterConditionBuilder.builder().andEqual("location","3楼").and(
     * <p>&emsp;&emsp;&emsp;&emsp;() ->FilterConditionBuilder.builder()
     * <p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;.andGreater("age", "60").orLess("age", "18").build()
     * <p>&emsp;&emsp;).build();
     * <p>&emsp;&emsp;表示" location = '3楼' and (age > 60 or age < 18) "
     *
     * @param filterConditionBuilder 过滤条件构造函数，函数应返回0个或多个过滤条件，组成一个“AND”子条件
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder and(Supplier<List<FilterCondition>> filterConditionBuilder) {
        this.addSubFilterConditions(filterConditionBuilder.get(), ExpressRelationType.And);
        return this;
    }

    /**
     * 在现有过滤条件后追加一个“OR”子条件
     * <p>例：subFilterConditions表示"age > 18 and age < 60"
     * <p>&emsp;&emsp;调用FilterConditionBuilder.builder().andEqual("location","3楼").or(subFilterConditions).build()
     * <p>&emsp;&emsp;表示" location = '3楼' or (age > 18 and age < 60) "
     *
     * @param subFilterConditions 0个或多个过滤条件，组成一个“OR”子条件
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder or(List<FilterCondition> subFilterConditions) {
        this.addSubFilterConditions(subFilterConditions, ExpressRelationType.Or);
        return this;
    }

    /**
     * 在现有过滤条件后追加一个“OR”子条件
     * <p>例：FilterConditionBuilder.builder().andEqual("location","3楼").or(
     * <p>&emsp;&emsp;&emsp;&emsp;()->FilterConditionBuilder.builder()
     * <p>&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;.andGreater("age", "18").andLess("age","60").build()
     * <p>&emsp;&emsp;).build();
     * <p>&emsp;&emsp;表示" location = '3楼' or (age > 18 and age < 60) "
     *
     * @param filterConditionBuilder 过滤条件构造函数，函数应返回0个或多个过滤条件，组成一个“OR”子条件
     * @return 添加此条件后的过滤条件建造器
     */
    public FilterConditionBuilder or(Supplier<List<FilterCondition>> filterConditionBuilder) {
        this.addSubFilterConditions(filterConditionBuilder.get(), ExpressRelationType.Or);
        return this;
    }

    //endregion 在现有过滤条件后追加子条件

    //region private method

    /**
     * 添加一个过滤条件
     *
     * @param fieldName    属性名称
     * @param compareType  比较符，仅支持ExpressCompareType.In或者ExpressCompareType.NotIn
     * @param value        值
     * @param valueType    值类型
     * @param relationType 与前一过滤条件的关系符
     */
    private void add(String fieldName, ExpressCompareType compareType, String value, ExpressValueType valueType, ExpressRelationType relationType) {
        FilterCondition filterCondition = new FilterCondition(0, fieldName, compareType, value, 0,
                ExpressRelationType.Empty, valueType);
        this.addFilterCondition(filterCondition, relationType);
    }

    /**
     * 添加一个比较符为IN或者NOT IN的过滤条件
     *
     * @param fieldName    属性名称
     * @param compareType  比较符，仅支持ExpressCompareType.In或者ExpressCompareType.NotIn
     * @param inValues     值，值类型为ExpressValueType.Value
     * @param relationType 与前一过滤条件的关系符
     */
    private void addInCondition(String fieldName, ExpressCompareType compareType, List<?> inValues,
                                ExpressRelationType relationType) {
        FilterCondition filterCondition = new FilterCondition();
        filterCondition.setlBracketCount(0);
        filterCondition.setFilterField(fieldName);
        filterCondition.setCompare(compareType);
        filterCondition.setInValues(inValues);
        filterCondition.setExpresstype(ExpressValueType.Value);
        filterCondition.setRBracketCount(0);
        filterCondition.setRelation(ExpressRelationType.Empty);
        this.addFilterCondition(filterCondition, relationType);
    }

    /**
     * 添加一个比较符为IN或者NOT IN的过滤条件
     *
     * @param fieldName         属性名称
     * @param compareType       比较符，仅支持ExpressCompareType.In或者ExpressCompareType.NotIn
     * @param bqlConditionValue bql，用于获取in的参数
     * @param relationType      与前一过滤条件的关系符
     */
    private void addInCondition(String fieldName, ExpressCompareType compareType, BqlConditionValue bqlConditionValue,
                                ExpressRelationType relationType) {
        FilterCondition filterCondition = new FilterCondition();
        filterCondition.setlBracketCount(0);
        filterCondition.setFilterField(fieldName);
        filterCondition.setCompare(compareType);
        filterCondition.setCustomConditionValue(bqlConditionValue);
        filterCondition.setExpresstype(ExpressValueType.Bql);
        filterCondition.setRBracketCount(0);
        filterCondition.setRelation(ExpressRelationType.Empty);
        this.addFilterCondition(filterCondition, relationType);
    }

    /**
     * 添加一个过滤条件
     *
     * @param condition    过滤条件
     * @param relationType 与前一过滤条件的关系符
     */
    private void addFilterCondition(FilterCondition condition, ExpressRelationType relationType) {
        checkFilterCondition(condition);
        if (!this.filterConditions.isEmpty()) {
            this.filterConditions.get(this.filterConditions.size() - 1).setRelation(relationType);
        }
        this.filterConditions.add(condition);
    }

    /**
     * 检查FilterCondition属性是否合法
     */
    private void checkFilterCondition(FilterCondition condition) {
        if (StringUtils.isBlank(condition.getFilterField())) {
            throw new IllegalFilterConditionArgsException("构造的过滤条件中fieldName不能为空字符串！");
        }
        if (condition.getExpresstype() == null) {
            throw new IllegalFilterConditionArgsException("构造的过滤条件中ExpressValueType属性不能为null！");
        }
        if (condition.getExpresstype() == ExpressValueType.Expression && StringUtils.isBlank(condition.getValue())) {
            throw new IllegalFilterConditionArgsException("当过滤条件中值类型为ExpressValueType.Expression时，value属性不能为空字符串！");
        }
        if (condition.getCompare() == ExpressCompareType.In || condition.getCompare() == ExpressCompareType.NotIn) {
            if (condition.getExpresstype() == ExpressValueType.Bql && condition.getCustomConditionValue() == null) {
                throw new IllegalFilterConditionArgsException("当比较符为in或notIn并且从Bql中取值时，必须传入BqlConditionValue对象！");
            } else if (condition.getExpresstype() == ExpressValueType.Value && condition.getInValues() == null) {
                throw new IllegalFilterConditionArgsException("当比较符为in或notIn并且直接传入待比较的数值集合List时，数值集合List不能为null！");
            }
        }
    }

    /**
     * 检查传入的FilterConditions中括号设置是否正确
     */
    private void checkBracketCount(List<FilterCondition> conditions) {
        int lBracketCount = 0;//模拟左括号出入栈
        for (FilterCondition condition : conditions) {
            //判断左括号数必须大于0（右括号数在FilterCondition里有检测）
            if (condition.getLBracketCount() < 0) {
                throw new IllegalFilterConditionArgsException("FilterCondition中左括号数不能小于0，请检查！");
            }
            lBracketCount += condition.getLBracketCount();
            lBracketCount -= condition.getRBracketCount();
            if (lBracketCount < 0) {
                throw new IllegalFilterConditionArgsException("多个FilterCondition中括号数未成对出现，请检查！");
            }
        }
        if (lBracketCount > 0) {
            throw new IllegalFilterConditionArgsException("多个FilterCondition中括号数未成对出现，请检查！");
        }
    }

    /**
     * 追加子条件在现有过滤条件后
     *
     * @param subFilterConditions 0个或多个过滤条件
     * @param expressRelationType 与现有条件的关系
     */
    private void addSubFilterConditions(List<FilterCondition> subFilterConditions, ExpressRelationType expressRelationType) {
        if (subFilterConditions == null || subFilterConditions.isEmpty()) {
            return;
        }
        checkBracketCount(subFilterConditions);
        if (!this.filterConditions.isEmpty()) {
            this.filterConditions.get(this.filterConditions.size() - 1).setRelation(expressRelationType);
        }
        int subConditionSize = subFilterConditions.size();
        if (subConditionSize > 1) {
            //当前已有条件且待添加里有多个条件时，未多个条件添加左右括号
            subFilterConditions.get(0)
                    .setlBracketCount(subFilterConditions.get(0).getLBracketCount() + 1);
            subFilterConditions.get(subConditionSize - 1)
                    .setRBracketCount(subFilterConditions.get(subConditionSize - 1).getRBracketCount() + 1);
        }
        this.filterConditions.addAll(subFilterConditions);
    }

    //endregion private method

}
